package com.comp6231.testcases;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketTimeoutException;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

import com.comp6231.common.Request;
//import com.comp6231.frontend.FrontEnd;
import com.comp6231.frontend.FrontEndInitiator;

public class FIFOTester implements Runnable {

	CyclicBarrier barrier;
	Request request;

	static String hostName = "localhost";
	static int port;
	static String entityName = "Front End";

	DatagramSocket socket = null;

	public FIFOTester(CyclicBarrier barrier, Request request) {
		super();
		this.barrier = barrier;
		this.request = request;
	}

	@Override
	public void run() {
		try {
			barrier.await();
			socket = new DatagramSocket();
			String messageString = request.createPacketString();
			byte[] messageBytes = messageString.getBytes();
			InetAddress add = InetAddress.getByName(hostName);
			DatagramPacket req = new DatagramPacket(messageBytes,
					messageString.length(), add, port);
			for (int i = 0; i < 3; i++) {
				socket.send(req);
				socket.setSoTimeout(20000);

				byte[] buffer = new byte[1000];
				DatagramPacket reply = new DatagramPacket(buffer, buffer.length);
				String replyMessage = "";

				try {
					socket.receive(reply);
					replyMessage = new String(reply.getData()).trim();
					System.out.println("Reply received for: "
							+ request.getRequestID());
					break;
				} catch (SocketTimeoutException e) {
					replyMessage = new String("no response");
					continue;
				}
			}

		} catch (InterruptedException | BrokenBarrierException | IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		//FrontEnd fe = new FrontEnd("localhost", "8898");
		try {
			Thread.sleep(20000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		//port = fe.leaderUDPPort;
		port = FrontEndInitiator.getLeaderUDPPort();
		final CyclicBarrier cb = new CyclicBarrier(10);
		Thread[] t = new Thread[10];
		String op = "Operation";
		String arg = "Arguments";
		for (int i = 0; i < t.length; i++) {
			String reqID = "R" + String.format("%04d", i);
			t[i] = new Thread(new FIFOTester(cb, new Request(hostName, port,
					entityName, reqID, op, arg)));
			t[i].start();
		}
	}
}
